using System.Collections.Generic;

public class CheckVaildInitPosition
{
    public List<Point> points = new List<Point>();

    public byte[] subBlock;

    private bool isReverse;

    private bool isUp;

    private int rootIndex;

    public void SetData(byte[] _subBlock, int _index, bool _isReverse)
    {
        points.Clear();
        subBlock = _subBlock;
        isReverse = _isReverse;
        rootIndex = _index;
        int num = 0;
        for (int i = 0; i < subBlock.Length; i++)
        {
            Point item = BlocksCoordinate.coordinate.coordinate.IndexToPuzzle(subBlock[i]);
            if (i == 0)
            {
                if (_isReverse)
                {
                    isUp = (((item.x + item.y) % 2 != 0) ? true : false);
                }
                else
                {
                    isUp = (((item.x + item.y) % 2 == 0) ? true : false);
                }
            }
            points.Add(item);
        }
    }

    public bool IsValidPosition(List<BoardInfo> boardInfos, Point currentRootPoint)
    {
        for (int i = 0; i < points.Count; i++)
        {
            Point gapPoint;
            int itemIndex = GetItemIndex(out gapPoint, boardInfos, currentRootPoint, i);
            if (itemIndex < 0)
            {
                return false;
            }
            if (boardInfos[itemIndex].index >= 0)
            {
                return false;
            }
            if (i == 0 && boardInfos[itemIndex].isUp != isUp && GameMode.gameMode == GameType.TRIANGLE)
            {
                return false;
            }
        }
        return true;
    }

    private int GetItemIndex(out Point gapPoint, List<BoardInfo> boardInfos, Point currentRootPoint, int index)
    {
        int x = currentRootPoint.x;
        Point point2 = points[0];
        int num = x - point2.x;
        int y = currentRootPoint.y;
        Point point3 = points[0];
        int num2 = y - point3.y;
        Point point4 = points[index];
        int x2 = point4.x + num;
        Point point5 = points[index];
        gapPoint = new Point(x2, point5.y + num2);
        Point point = new Point(gapPoint.x, gapPoint.y);
        return boardInfos.FindIndex((BoardInfo item) => item.point == point);
    }

    public void SetInitValidPosition(List<BoardInfo> boardInfos, Point currentRootPoint, bool isSet)
    {
        for (int j = 0; j < points.Count; j++)
        {
            Point gapPoint;
            int itemIndex = GetItemIndex(out gapPoint, boardInfos, currentRootPoint, j);
            if (itemIndex < 0)
            {
                continue;
            }
            boardInfos[itemIndex].index = ((!isSet) ? (-1) : rootIndex);
            List<Point> neighborPoints = new List<Point>();
            if (GameMode.gameMode == GameType.TRIANGLE)
            {
                neighborPoints = GetTriangleNeighborPoints(gapPoint);
            }
            else if (GameMode.gameMode == GameType.SQUARE)
            {
                neighborPoints = GetSquareNeighborPoints(gapPoint);
            }
            else if (GameMode.gameMode == GameType.HEXA)
            {
                neighborPoints = GetHexaNeighborPoints(gapPoint);
            }
            else if (GameMode.gameMode == GameType.RHOMBUS)
            {
                neighborPoints = GetRhombusNeighborPoints(gapPoint);
            }
            else if (GameMode.gameMode == GameType.TANGRAM)
            {
                neighborPoints = GetTangramNeighborPoints(gapPoint);
            }
            int i;
            for (i = 0; i < neighborPoints.Count; i++)
            {
                int num = boardInfos.FindIndex((BoardInfo item) => item.point == neighborPoints[i]);
                if (num >= 0)
                {
                    boardInfos[num].index = ((!isSet) ? (-1) : rootIndex);
                }
            }
        }
    }

    public Point PixBlockPosition(List<BoardInfo> boardInfos)
    {
        for (int i = 0; i < BlocksCoordinate.coordinate.initCoordinate.height; i++)
        {
            for (int j = 0; j < BlocksCoordinate.coordinate.initCoordinate.width; j++)
            {
                if (IsValidPosition(boardInfos, new Point(j, i)))
                {
                    return new Point(j, i);
                }
            }
        }
        return new Point(-100, -100);
    }

    private List<Point> GetTriangleNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        list.Add(new Point(point.x - 1, point.y));
        list.Add(new Point(point.x + 1, point.y));
        list.Add(new Point(point.x - 2, point.y));
        list.Add(new Point(point.x + 2, point.y));
        list.Add(new Point(point.x, point.y + 1));
        list.Add(new Point(point.x, point.y - 1));
        list.Add(new Point(point.x - 1, point.y - 1));
        list.Add(new Point(point.x - 1, point.y + 1));
        list.Add(new Point(point.x + 1, point.y - 1));
        list.Add(new Point(point.x + 1, point.y + 1));
        bool flag = false;
        if ((!isReverse) ? (((point.x + point.y) % 2 == 0) ? true : false) : (((point.x + point.y) % 2 != 0) ? true : false))
        {
            list.Add(new Point(point.x - 2, point.y - 1));
            list.Add(new Point(point.x + 2, point.y - 1));
        }
        else
        {
            list.Add(new Point(point.x - 2, point.y + 1));
            list.Add(new Point(point.x + 2, point.y + 1));
        }
        return list;
    }

    private List<Point> GetSquareNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        list.Add(new Point(point.x - 1, point.y));
        list.Add(new Point(point.x + 1, point.y));
        list.Add(new Point(point.x, point.y + 1));
        list.Add(new Point(point.x, point.y - 1));
        list.Add(new Point(point.x - 1, point.y - 1));
        list.Add(new Point(point.x - 1, point.y + 1));
        list.Add(new Point(point.x + 1, point.y - 1));
        list.Add(new Point(point.x + 1, point.y + 1));
        return list;
    }

    private List<Point> GetHexaNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        list.Add(new Point(point.x - 1, point.y + ((point.x % 2 != 0) ? 1 : 0)));
        list.Add(new Point(point.x - 1, point.y - ((point.x % 2 == 0) ? 1 : 0)));
        list.Add(new Point(point.x + 1, point.y + ((point.x % 2 != 0) ? 1 : 0)));
        list.Add(new Point(point.x + 1, point.y - ((point.x % 2 == 0) ? 1 : 0)));
        list.Add(new Point(point.x, point.y + 1));
        list.Add(new Point(point.x, point.y - 1));
        return list;
    }

    private List<Point> GetRhombusNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        list.Add(new Point(point.x - 1, point.y + ((point.x % 2 != 0) ? 1 : 0)));
        list.Add(new Point(point.x - 1, point.y - ((point.x % 2 == 0) ? 1 : 0)));
        list.Add(new Point(point.x + 1, point.y + ((point.x % 2 != 0) ? 1 : 0)));
        list.Add(new Point(point.x + 1, point.y - ((point.x % 2 == 0) ? 1 : 0)));
        list.Add(new Point(point.x, point.y + 1));
        list.Add(new Point(point.x, point.y - 1));
        list.Add(new Point(point.x - 2, point.y));
        list.Add(new Point(point.x + 2, point.y));
        return list;
    }

    private List<Point> GetTangramNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        list = GetSquareNeighborPoints(point);
        list.Add(new Point(point.x - 2, point.y));
        list.Add(new Point(point.x + 2, point.y));
        list.Add(new Point(point.x + 3, point.y));
        list.Add(new Point(point.x - 3, point.y));
        list.Add(new Point(point.x - 2, point.y + 1));
        list.Add(new Point(point.x - 2, point.y - 1));
        list.Add(new Point(point.x + 2, point.y + 1));
        list.Add(new Point(point.x + 2, point.y - 1));
        list.Add(new Point(point.x + 3, point.y - 1));
        list.Add(new Point(point.x + 3, point.y + 1));
        list.Add(new Point(point.x - 3, point.y - 1));
        list.Add(new Point(point.x - 3, point.y + 1));
        return list;
    }
}
